#include "ac_tlm_dsum.h"

using user::ac_tlm_dsum;


ac_tlm_dsum::ac_tlm_dsum( sc_module_name module_name , int k ) :sc_module( module_name ){
	target_export( *this );

	/// Initialize memory vector
    memory = new uint8_t[ 24 ];
    for(int i=0 ; i < 24 ; i++){
	    memory[i] = 0;
    }
}

/// Destructor
ac_tlm_dsum::~ac_tlm_dsum() {
	delete [] memory;
}

#define DEBUG 1
/**
 * Escreve o valor pedido
 */
ac_tlm_rsp_status ac_tlm_dsum::writem( const uint32_t &a , const uint32_t &d ){
	uint32_t dest;
	uint8_t *temp = new uint8_t[4];
	uint8_t *temp_ajustado = new uint8_t[4];
	
	*((uint32_t*)(temp)) = d;
	
	temp_ajustado[3] = temp[0];
	temp_ajustado[2] = temp[1];
	temp_ajustado[1] = temp[2];
	temp_ajustado[0] = temp[3];
	
	///Remap 
	switch(a)
	{
		case 0:
			dest = 4;
			break;
		case 4:
			dest = 0;
			break;
		case 8:
			dest = 12;
			break;
		case 12:
			dest = 8;
			break;
		default:
			return ERROR; // Não escreva no lugar errado!
	}



	*((uint32_t*)(&(memory[dest]))) = *((uint32_t*)temp_ajustado);

	return SUCCESS;
}

ac_tlm_rsp_status ac_tlm_dsum::readm( const uint32_t &a , uint32_t &d ){
	double d1, d2, d3;
	uint32_t dest;

	//cout << "Endereco de leitura " << a << endl;

	if (a == 16)
	{
		d1 = *((double*)(&memory[0]));
		d2 = *((double*)(&memory[8]));
		//printf("d1 >>> %f\n", d1);
		//printf("d2 >>> %f\n", d2);
		
		
		
		d3 = d1 + d2;

		//cout << "resultado da soma  " << d3 << endl;
		*((double*)(&memory[16])) = d3;
	}


		
	
	uint8_t *temp = new uint8_t[4];
	uint8_t *temp_ajustado = new uint8_t[4];
	
	
	///Remap 
	switch(a)
	{
		case 0:
				dest = 4;
				break;
			case 4:
				dest = 0;
				break;
			case 8:
				dest = 12;
				break;
			case 12:
				dest = 8;
				break;
			case 16:
				dest = 20;
				break;
			case 20:
				dest= 16;
				break;
			default:
				return ERROR; // Não escreva no lugar errado!
	}


	*((uint32_t*)(temp)) = *((uint32_t *) &memory[dest]);
	
	temp_ajustado[3] = temp[0];
	temp_ajustado[2] = temp[1];
	temp_ajustado[1] = temp[2];
	temp_ajustado[0] = temp[3];

	

	*((uint32_t *) &d) = *((uint32_t*)temp_ajustado);;
	return SUCCESS;
}





